package com.soap.desensitize.posterity;

import com.soap.desensitize.encry.IDesensitization;
import com.soap.desensitize.exception.strategy.DecodeException;
import com.soap.desensitize.exception.strategy.EncodeException;
import com.soap.desensitize.posterity.collection.ListDesensitization;
import com.soap.desensitize.posterity.collection.MapDesensitization;
import com.soap.desensitize.posterity.entity.EntityDesensitization;
import com.soap.desensitize.posterity.entity.IEntity;

import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @desc	对象脱敏功能扩展抽象基类
 * @author 	Administrator
 * @time	2022-04-21
 */
public abstract class AbstractPosterity<T> {
    protected IDesensitization encry;

    /**
     * @desc 有参构造器
     * @param encry
     */
    public AbstractPosterity(IDesensitization encry) {
        this.encry = encry;
    }

    /**
     * @param data 需要解密的值
     * @return
     * @throws NoSuchAlgorithmException
     * @throws EncodeException
     * @desc 判断类型并且加密
     */
    public Object judgeAndDecode(Object data) throws DecodeException {
        Object str = null;

        try {
            if (data instanceof Number){
                str = encry.decode(data);
            }
            else if (data instanceof String){
//                System.out.println(data);
                str = encry.decode(data+"");
            }
            else if (data instanceof Boolean){
                str = encry.decode(data.toString());
            }
            else if (data instanceof Date){
//                str = encry.decode(data.toString());
                throw new DecodeException("未添加日期对象加密策略，不推荐使用");
            }
            else if (data instanceof List){
                str = ListDesensitization.getInstance(encry).decode((List) data);
            }
            else if (data instanceof Map){
                str = MapDesensitization.getInstance(encry).decode((Map) data);
            }else if (data instanceof IEntity){
                str = EntityDesensitization.getInstance(encry).decode(data);
            }else {
                throw new DecodeException("暂不支持该类型解密 classType:"+data.getClass().getTypeName());
            }
        } catch (DecodeException e) {
            throw new DecodeException("解密异常");
        }
        return str;
    }
    /**
     * @param data 需要加密的值
     * @return
     * @throws NoSuchAlgorithmException
     * @throws EncodeException
     * @desc 判断类型并且加密
     */
    public Object judgeAndEncode(Object data) throws EncodeException {
        Object str = null;

        try {
            if (data instanceof Number){
                str = encry.encode(data);
            }
            else if (data instanceof String){
                str = encry.encode(data);
            }
            else if (data instanceof Boolean){
                str = encry.encode(data.toString());
            }
            else if (data instanceof Date){
//                str = encry.decode(data.toString());
                throw new EncodeException("未添加日期对象加密策略");
            }
            else if (data instanceof List){
                str = ListDesensitization.getInstance(encry).encode((List) data);
            }
            else if (data instanceof Map){
                str = MapDesensitization.getInstance(encry).encode((Map) data);
            }else if (data instanceof IEntity){
                str = EntityDesensitization.getInstance(encry).encode(data);
            }
        }catch (EncodeException e) {
            throw new EncodeException("加密异常");
        }
        return str;
    }


    public abstract T encode(T data) throws EncodeException;

    public abstract T decode(T data ) throws DecodeException;

    public IDesensitization getEncry() {
        return encry;
    }

    public void setEncry(IDesensitization encry) {
        this.encry = encry;
    }



}
